<template>
  <div ref="popoverRef" class="x-popover">
    <div v-show="visible" ref="popoverWrapperRef" class="popover-wrapper" :class="{ 'popover-wrapper-active': visible }">
      <div class="popover-wrapper-content" :style="{ 'marginLeft': PADDING_RIGHT + 'px' }">
        <div class="popover-wrapper-bg"></div>
        <slot name="content"></slot>
      </div>
    </div>
    <span ref="triggerWrapperRef" class="trigger-wrapper">
      <slot></slot>
    </span>
  </div>
</template>

<script lang="ts" setup name="XPopover">
const props = defineProps({
  position: {
    type: String,
    default: 'left',
  },
  trigger: {
    type: String,
    default: 'click'
  },
},
)
const popoverRef = ref(null)
const triggerWrapperRef = ref(null)
const popoverWrapperRef = ref(null)
const visible = ref(false)
const MIN_TOP = 114 // 距顶部最小距离
const marginRight = ref(0) // 正文padding-right
const PADDING_RIGHT = 21 // hover正文和菜单选项距离
const DIFF_HEIGHT = 43 // 播放节点距离顶部距离

const positionContent = () => {
  document.body.appendChild(popoverWrapperRef.value)
  let { height, top, left, width } = triggerWrapperRef.value.getBoundingClientRect()
  let { height: height2 } = popoverWrapperRef.value.
    getBoundingClientRect()
  let menu: LooseObject = document.querySelector('.web-menu')
  let { left: menuLeft } = menu.getBoundingClientRect()

  let diff = top + (height - height2) / 2 + window.pageYOffset
  let minTop = diff
  // 计算popover正文距离菜单margin-right
  marginRight.value = left - menuLeft + PADDING_RIGHT

  // 若超出侧边菜单长度 对齐菜单底部
  if (diff + height2 > MIN_TOP + menu.offsetHeight) {
    minTop = MIN_TOP + menu.offsetHeight - height2
  }
  // 若小于最低距离顶部高度取值
  if (minTop < MIN_TOP) {
    minTop = MIN_TOP
  }

  let positions = {
    top: minTop,
    left: left
  }
  popoverWrapperRef.value.style.left = positions.left + 'px'
  popoverWrapperRef.value.style.top = positions.top + 'px'
  popoverWrapperRef.value.style.transform = `translateX(${width}px)`
}

const handleClick = (event) => {
  if (triggerWrapperRef.value.contains(event.target)) {
    if (visible.value === true) {
      close()
    } else {
      onShow()
    }
  }
}
const onShow = () => {
  visible.value = true
  nextTick(() => {
    positionContent()
    document.addEventListener('click', eventHandler)
    if (props.trigger !== 'click') {
      popoverWrapperRef.value.addEventListener('mouseenter', onShow)
      popoverWrapperRef.value.addEventListener('mouseleave', close)
      // 自动定位到播放内容
      const res = popoverWrapperRef.value.querySelector('.child-list')
      const child: HTMLBaseElement = popoverWrapperRef.value.querySelector('.child-item-active')
      if (child?.offsetTop) {
        res.scrollTop = child?.offsetTop ? Number(child.offsetTop) - DIFF_HEIGHT : 0
      }
    }
  })
}
const close = () => {
  visible.value = false
  document.removeEventListener('click', eventHandler)
  // document.body.removeChild(popoverWrapperRef.value)
}

const eventHandler = (e) => {
  if (popoverRef.value && (popoverRef.value === e.target || popoverRef.value.contains(e.target))) {
    return
  }
  if (popoverWrapperRef.value && (popoverWrapperRef.value === e.target || popoverWrapperRef.value.contains(e.target))) {
    return
  }
  close()
}

onMounted(() => {
  if (props.trigger === 'click') {
    popoverRef.value.addEventListener('click', handleClick)
  } else {
    popoverRef.value.addEventListener('mouseenter', onShow)
    popoverRef.value.addEventListener('mouseleave', close)
  }
})

onBeforeUnmount(() => {
  if (props.trigger === 'click') {
    popoverRef.value.removeEventListener('click', handleClick)
  } else {
    popoverRef.value.removeEventListener('mouseenter', onShow)
    popoverRef.value.removeEventListener('mouseleave', close)
    popoverWrapperRef?.value?.removeEventListener('mouseenter', onShow)
    popoverWrapperRef?.value?.removeEventListener('mouseleave', close)
  }
  visible.value && popoverWrapperRef?.value && document.body.removeChild(popoverWrapperRef?.value)
})


</script>

<style lang="scss" scoped>
.x-popover {
  position: relative;
}

.popover-wrapper {
  position: absolute;
  border-radius: 20px;
  z-index: 200;

  .popover-wrapper-content {
    position: relative;
    border: 1px solid rgba(255, 255, 255, 0.8);
    background: rgba(221, 236, 255, 0.4);
    box-shadow: 0px 2px 20px 0px rgba(13, 25, 55, 0.05);
    width: 409px;
    max-height: 498px;
    border-radius: 20px;
  }

  .popover-wrapper-bg {
    @apply absolute h-full w-full backdrop-blur-15px backdrop-filter -z-1 overflow-hidden;
    border-radius: 20px;
    content: '';
  }

  &.position-left {
    transform: translateX(100%);
  }
}
</style>